#ifndef XLCOMM_NET_TIMERQUEUE_H_
#define XLCOMM_NET_TIMERQUEUE_H_

#include <set>
#include <vector>

#include "xlcomm/base/date_time.h"
#include "xlcomm/net/detail/channel.h"
#include "xlcomm/net/detail/timer.h"
#include "xlcomm/net/event_loop.h"
#include "xlcomm/net/timer_id.h"
#include "xlcomm/noncopyable.h"

namespace xlcomm {
namespace net {

// 定时器任务队列
class TimerQueue : noncopyable {
 public:
  TimerQueue(EventLoop* loop);
  ~TimerQueue();

  // 添加定时任务（支持多线程调用）
  TimerId AddTimer(TimerCallback cb, Timestamp when_expire,
                   double interval_second = 0.0);

  // 取消定时任务
  // void Cancel(TimerId timer_id);

 private:
  // FIXME: use unique_ptr<Timer> instead of raw pointers.
  // This requires heterogeneous comparison lookup (N3465) from C++14
  // so that we can find an T* in a set<unique_ptr<T>>.
  using Entry = std::pair<Timestamp, Timer*>;
  using TimerSet = std::set<Entry>;

  // 在EventLoop线程添加定时任务
  void AddTimerInLoop(Timer* timer);
  // 处理timer_fd_可读事件
  void HandleRead();
  // 获取到期的任务列表，并从任务队列移除
  std::vector<Entry> GetExpired(Timestamp now);
  // 重置需要重复的到期任务
  void Reset(const std::vector<Entry>& expired, Timestamp now);
  // 插入定时任务到队列，返回是否改变了最早到期时间
  bool Insert(Timer* timer);

  EventLoop* loop_;
  const int timer_fd_;
  Channel timer_channel_;
  TimerSet timers_;  // 以到期时间排序
};

}  // namespace net
}  // namespace xlcomm

#endif  // XLCOMM_NET_TIMERQUEUE_H_